#ifndef COMMON_WIN32THREADHANDLE_H
#define COMMON_WIN32THREADHANDLE_H


#include "Thread.h"
#include "Win32Handle.h"
#include "error.h"
#include <windows.h>


namespace common { class ThreadStartRoutine; } 
namespace common { class SyncObject; } 

namespace common {

//Specialization for Win32 threads
class Win32Thread : public Thread, public Win32SyncObject {
  public:
    Win32Thread();

    virtual ~Win32Thread();

    Win32Thread(const Win32Thread & source);

    virtual Thread & operator=(const Thread & source);

    //Compares two thread handles
    virtual bool operator==(const Thread * theOther);

    //Creates new thread as suspended.
    virtual Error::code Create(const ThreadStartRoutine & threadStart);

    //Returns object of current (calling) thread.
    virtual Error::code Current();

    //Starts newly created thread.
    virtual Error::code Start();

    //Resumes this thread, or reduces its suspension count.
    Error::code Resume();

    //Suspends the thread, or increases its suspension counter.
    Error::code Suspend();

    //Terminates Running thread. Should be used with causion.
    virtual Error::code Terminate();

    //Gives execution time, to another thread that is waiting.
    //Error if no waiting threads.
    virtual Error::code Switch();

    //Suspends current thread and yields for given time (in miliseconds)
    virtual Error::code Sleep(unsigned long int sleepTime);

    //Closes Handle to this synchronization object and does some cleanup.
    virtual Error::code Close();

    //Standard wait for single sync object.
    virtual Error::code WaitFor(unsigned int timeout);

    //Waits for multiple sync objects.
    virtual Error::code WaitForMultiple(unsigned int count, const SyncObject * handleList, bool waitAll, unsigned int milliseconds);


  private:
    //Our own startup routine for new thread.
    static DWORD WINAPI ThreadProc(LPVOID lpParameter);


  protected:
    //To avoid exceptions during copying of these objects. Only Thread Ids are transfered.
    //Later this method is responsible for preparing proper Handle to use.
    void Prepare();

    //Returns windows handle to this object.
    virtual Error::code GetHandle(DWORD & handle);


  private:
    //System native handle to the thread.
    HANDLE mNativeHandle;

    DWORD mNativeThreadId;

};

} // namespace common
#endif
